﻿using System;
using System.Collections.Generic;
using System.Text;
using BF.IBLL.BaseSystem;
using BF.IDAL.BaseSystem;
using BF.Model;
using BF.Infrastructure;
using System.Linq;
using System.Web.Security;
using BF.Membership.MembershipEF;
using BF.Membership.BLL;
using System.Linq.Expressions;
using BF.Membership;
//using BF.

namespace BF.BLL.BaseSystem
{
    public class Sys_PermissionBLL : Isys_PermissionBLL
    {
        private readonly Isys_PermissionDAL iPermissionDal;
        private readonly Isys_UserInfoDAL iUserInfoDal;
        private readonly Isys_FunctionDAL iFunctionDAL;
        private readonly Isys_RoleInfoBLL iRoleInfoBLL;
        private readonly IUnitOfWork<WSJD_BaseFrameworkEntities> uwork;

        public Sys_PermissionBLL(IUnitOfWork<WSJD_BaseFrameworkEntities> uwork,
            Isys_PermissionDAL iPermissionDal,
            Isys_UserInfoDAL iUserInfoDal,
            Isys_FunctionDAL iFunctionDAL,
            Isys_RoleInfoBLL iRoleInfoBLL)
        {
            this.iPermissionDal = iPermissionDal;
            this.iUserInfoDal = iUserInfoDal;
            this.iFunctionDAL = iFunctionDAL;
            this.iRoleInfoBLL = iRoleInfoBLL;
            this.uwork = uwork;
            //this.uwork.LogEvent = new LogEventHandler(Sys_LogBLL.WriteLog);
        }

        #region Isys_PermissionBLL 成员

        public List<sys_Function> GetFunctionListByRoleName(string roleName)
        {
            if (String.IsNullOrEmpty(roleName))
                return new List<sys_Function>();
            AspnetRolesBLL roleBLL = new AspnetRolesBLL();
            aspnet_Roles aspnetRoles = roleBLL.GetModelByName(roleName);
            return iPermissionDal
                .GetList(P => P.gRoleID == aspnetRoles.RoleId)
                .ToList()
                .Select(P => P.sys_Function)
                .Where(P => P.bFlag == true)
                .ToList();
        }

        public List<sys_Function> GetFunctionListByUserID(string userID)
        {
            sys_UserInfo userInfo = iUserInfoDal
                .GetModelByCondition(P => P.gUserID.Equals(new Guid(userID)));
            string[] roles = Roles.GetRolesForUser(userInfo.sLoginName);
            AspnetRolesBLL roleBLL = new AspnetRolesBLL();

            Guid[] rolesList = roleBLL
                .GetList(roles)
                .Select(P => P.RoleId)
                .ToArray();
            return iPermissionDal.
                GetList(C => rolesList.Contains(C.gRoleID))
                .ToList()
                .Select(P => P.sys_Function)
                .Where(P => P.bFlag == true)
                .GroupBy(P => P)
                .Select(P => P.Key)
                .ToList();
        }

        private List<sys_Function> GetFunctionListByUserName(string userName)
        {
            sys_UserInfo userInfo = iUserInfoDal
                .GetModelByCondition(P => P.sUserName == userName);
            string[] roles = Roles.GetRolesForUser(userInfo.sLoginName);
            AspnetRolesBLL roleBLL = new AspnetRolesBLL();

            Guid[] rolesList = roleBLL.GetList(roles).
                Select(P => P.RoleId).ToArray();
            return iPermissionDal.
                GetList(C => rolesList.Contains(C.gRoleID))
                .ToList()
                .Select(P => P.sys_Function)
                .Where(P => P.bFlag == true)
                .GroupBy(P => P)
                .Select(P => P.Key)
                .ToList();
        }

        /// <summary>
        /// 设置角色权限
        /// </summary>
        /// <param name="functionIDList"></param>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public bool SetRolePermission(List<string> functionIDList,
            string roleName, string currentLoginName)
        {
            AspnetRolesBLL roleBLL = new AspnetRolesBLL();
            aspnet_Roles aspnetRoles = roleBLL.GetModelByName(roleName);
            Guid roleID = aspnetRoles.RoleId;
            List<sys_Permission> oldList = iPermissionDal
                .GetList(P => P.gRoleID == roleID);//GetFunctionListByRoleName(roleName);
            string[] oldFunctionIDs = oldList
                .Select(P => P.sys_Function.gKey.ToString())
                .ToArray();
            //该角色新增的功能
            foreach (var item in functionIDList)
            {
                if (!string.IsNullOrEmpty(item) && !oldFunctionIDs.Contains(item))
                    iPermissionDal.Add(new sys_Permission()
                    {
                        gKey = Guid.NewGuid(),
                        gRoleID = roleID,
                        gFunctionKey = new Guid(item)
                    });
            }
            //该角色去除的功能
            foreach (var item in oldList)
            {
                if (!functionIDList.Contains(item.gFunctionKey.ToString()))
                {
                    iPermissionDal.Delete(item);
                    //处理子集 继承权限的应用
                    RemoveChildRolePermission(aspnetRoles.RoleName, currentLoginName, item.gFunctionKey);
                }
            }
            if (uwork.Commit() > 0)
                return true;
            else
                return false;
        }
        /// <summary>
        /// 处理子集 继承权限的应用
        /// </summary>
        /// <param name="roleName"></param>
        /// <param name="currentLoginName"></param>
        /// <param name="functionKey"></param>
        private void RemoveChildRolePermission(string roleName, string currentLoginName, Guid functionKey)
        {
            //取出具备当前角色的所有User
            string[] inRoleUsers = System.Web.Security.Roles.GetUsersInRole(roleName);
            //存在用户使用该角色执行if内容
            if (inRoleUsers != null && inRoleUsers.Length > 0)
            {
                //用户集合中不能包含当前操作该功能的用户，否则会有问题
                inRoleUsers = inRoleUsers.Where(p => p != currentLoginName).ToArray();
                //遍历当前用户集合
                foreach (var itemUser in inRoleUsers)
                {
                    sys_UserInfo tmpUser = iUserInfoDal.GetModelByCondition(p => p.sLoginName == itemUser);
                    //取得当前用户所创建的角色
                    List<sys_RoleInfo> childRoleList = iRoleInfoBLL.GetRoleCreateByUserId(tmpUser.gUserID).
                        Where(p => p.gCreateUserId == tmpUser.gUserID).ToList();

                    //当前用户存在自定义的角色进入if内容
                    if (childRoleList != null && childRoleList.Count > 0)
                    {
                        foreach (var childRoleitem in childRoleList)
                        {
                            //具体处理用户自定义角色(保持权限与最大权限进行联动)
                            List<sys_Permission> deletePermission =
                                iPermissionDal.GetList(p => p.gRoleID == childRoleitem.gRoleId
                                    && p.gFunctionKey == functionKey);
                            if (deletePermission != null && deletePermission.Count > 0)
                            {
                                foreach (var deletePermissionItem in deletePermission)
                                { iPermissionDal.Delete(deletePermissionItem); }
                            }
                            aspnet_Roles tmpAspRole = iRoleInfoBLL.GetRoleById(childRoleitem.gRoleId);
                            if (tmpAspRole != null)
                            { RemoveChildRolePermission(tmpAspRole.RoleName, itemUser, functionKey); }
                        }
                    }
                }
            }
        } 

        public bool Delete(Expression<Func<sys_Permission, bool>> predicate)
        {
            iPermissionDal.Delete(predicate);
            return uwork.Commit() > 0;
        }

        public List<sys_Function> GetFunctionListByUrl(string userName,
            string url)
        {
            sys_Function model = GetFunctionListByUserName(userName)
                .Where(P => P.sPath == url)
                .FirstOrDefault();
            return iFunctionDAL.GetList(P => P.gParentKey == model.gKey);
        }

        #endregion


        public bool DeleteRole(string roleName)
        {
            bool result = false;
            try
            {
                AspnetRolesBLL roleBLL = new AspnetRolesBLL();
                aspnet_Roles aspnetRoles = roleBLL.GetModelByName(roleName);
                if (roleBLL.DeleteByRoleName(roleName))//删除角色
                {
                    iPermissionDal.Delete(P => P.gRoleID == aspnetRoles.RoleId);
                    iRoleInfoBLL.DeleteRole(aspnetRoles.RoleId);
                }
                result = true;
            }
            catch
            { }
            return result;
        }

        public List<sys_Function> GetFunctionListByAdmin()
        {
            return iPermissionDal.
                GetList(C=>true)
                .ToList()
                .Select(P => P.sys_Function)
                .Where(P => P.bFlag == true)
                .GroupBy(P => P)
                .Select(P => P.Key)
                .ToList();
        }
    }
}
